#define  _CRT_SECURE_NO_WARNINGS
#include "SList.h"

SListNode* buyNewNode(SListDatatype x)
{
	SListNode* node = (SListNode*)malloc(sizeof(SListNode));
	if (!node)
	{
		perror("buyNewNode::malloc");
		return NULL;
	}
	node->val = x;
	node->next = NULL;
	return node;
}

void SListPrint(SListNode* plist)
{
	while (plist)
	{
		printf("%d->", plist->val);
		plist = plist->next;
	}
	printf("NULL\n");
}

void SListPushFront(SListNode** pplist, SListDatatype x)
{
	assert(pplist);
	SListNode* newnode = buyNewNode(x);
	newnode->next = *pplist;
	*pplist = newnode;
}

void SListPushBack(SListNode** pplist, SListDatatype x)
{
	assert(pplist);
	SListNode* newnode = buyNewNode(x);
	if (!(*pplist))
	{
		*pplist = newnode;
		return;
	}
	SListNode* cur = *pplist;
	while (cur->next)
	{
		cur = cur->next;
	}
	cur->next = newnode;
}

void SListPopFront(SListNode** pplist)
{
	assert(pplist);
	assert(*pplist);
	SListNode* tmp = *pplist;
	*pplist = (*pplist)->next;
	free(tmp);
}

void SListPopBack(SListNode** pplist)
{
	assert(pplist);
	assert(*pplist);

	SListNode* cur = *pplist;
	if (cur->next == NULL)
	{
		free(*pplist);
		*pplist = NULL;
		return;
	}
	while (cur->next->next)
	{
		cur = cur->next;
	}
	free(cur->next);
	cur->next = NULL;
}

SListNode* SListFind(SListNode* plist, SListDatatype tgt)
{
	assert(plist);
	while (plist)
	{
		if (plist->val == tgt)
		{
			return plist;
		}
		plist = plist->next;
	}
	return NULL;
}

void SListDestroy(SListNode** pplist)
{
	assert(pplist);
	assert(*pplist);
	SListNode* cur = *pplist, * tmp;
	while (cur)
	{
		tmp = cur;
		cur = cur->next;
		free(tmp);
	}
	*pplist = NULL;
}

void SListPushPosBack(SListNode** pplist, SListNode* pos, SListDatatype x)
{
	assert(pplist);
	assert(pos);
	SListNode* newnode = buyNewNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

void SListPushPosFront(SListNode** pplist, SListNode* pos, SListDatatype x)
{
	assert(pplist);
	assert(pos);
	if (*pplist == pos)
	{
		SListPushFront(pplist, x);
		return;
	}
	SListNode* cur = *pplist;
	while (cur->next != pos)
	{
		cur = cur->next;
	}
	SListNode* newnode = buyNewNode(x);
	newnode->next = pos;
	cur->next = newnode;
}

void SListPopPosBack(SListNode** pplist, SListNode* pos)
{
	assert(pplist);
	assert(pos);
	assert(pos->next);
	SListNode* tmp = pos->next;
	pos->next = pos->next->next;
	free(tmp);
}

void SListPopPos(SListNode** pplist, SListNode* pos)
{
	assert(pplist);
	assert(pos);
	if (pos == *pplist)
	{
		SListPopFront(pplist);
		return;
	}
	SListNode* cur = *pplist, * tmp;

	while (cur && cur->next != pos)
	{
		cur = cur->next;
	}
	if (cur)
	{
		tmp = cur->next;
		cur->next = tmp->next;
		free(tmp);
	}
}